

from . import RSA
from . import pkcs1_15
from . import SHA256
from . import b64encode
from . import time
from . import random
from . import requests
from . import json
import hashlib
import re


def format_url(params, api_key=None):
    """
    字典序排序
    :param params:
    :param api_key:
    :return:
    """
    url = "&".join(['%s=%s' % (key, params[key]) for key in sorted(params)])
    if api_key:
        url = '%s&key=%s' % (url, api_key)
    return url


def calculate_sign(params, api_key):
    """
    计算签名
    :param params:
    :param api_key:
    :return:
    """
    # 签名步骤一：按字典序排序参数, 在string后加入KEY
    url = format_url(params, api_key)
    # 签名步骤二：MD5加密, 所有字符转为大写
    return hashlib.md5(url.encode('utf-8')).hexdigest().upper()


def dict_to_xml(params):
    xml = ["<xml>", ]
    for k, v in params.items():
        xml.append('<%s>%s</%s>' % (k, v, k))
    xml.append('</xml>')
    return ''.join(xml)


def dict_to_xml2(params):
    xml = ["<xml>", ]
    for k, v in params.items():
        xml.append('<%s><![CDATA[%s]]></%s>' % (k, v, k))
    xml.append('</xml>')
    return ''.join(xml)


def xml_to_dict(xml):
    xml = xml.strip()
    if xml[:5].upper() != "<XML>" and xml[-6:].upper() != "</XML>":
        return None, None

    result = {}
    sign = None
    content = ''.join(xml[5:-6].strip().split('\n'))

    pattern = re.compile(r"<(?P<key>.+)>(?P<value>.+)</(?P=key)>")
    m = pattern.match(content)
    while m:
        key = m.group("key").strip()
        value = m.group("value").strip()
        if value != "<![CDATA[]]>":
            pattern_inner = re.compile(r"<!\[CDATA\[(?P<inner_val>.+)\]\]>")
            inner_m = pattern_inner.match(value)
            if inner_m:
                value = inner_m.group("inner_val").strip()
            if key == "sign":
                sign = value
            else:
                result[key] = value

        next_index = m.end("value") + len(key) + 3
        if next_index >= len(content):
            break
        content = content[next_index:]
        m = pattern.match(content)

    return sign, result


class WxPayUtilV2:
    '''
    微信支付
    '''
    mch_appid = "wxd77d18834962dada"
    mchid = "1604331286"
    api_key = "dc3f008bea694461bf3af165ad37a67a"

    def wx_ent_pay(self, orderId: str, openId: str, re_user_name: str):
        '''
        微信企业付款到个人
        '''
        url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"

        nonce_str = str(random.randint(100000, 10000000))
        params = {}
        params["mch_appid"] = self.mch_appid
        params["mchid"] = self.mchid
        params["partner_trade_no"] = orderId
        params["check_name"] = "FORCE_CHECK"
        params["re_user_name"] = re_user_name
        params["amount"] = 100
        params["desc"] = "提现"
        params["openid"] = openId

        params["nonce_str"] = nonce_str

        sign = calculate_sign(params, self.api_key)
        params["sign"] = sign
        xml = dict_to_xml(params)

        response = requests.post(url,
                                 data=xml.encode('utf-8'),
                                 cert=("apiclient_cert.pem", "apiclient_key.pem"))
        
        response = xml_to_dict(response.text)
        print(response)
